package com.ruoyi.project.modules.table.service.impl;

import java.util.*;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.project.modules.interfaceObject.domain.InterfaceObject;
import com.ruoyi.project.modules.interfaceinfo.domain.InterfaceInfo;
import com.ruoyi.project.modules.parameter.domain.InterfaceParamsFieldRelation;
import com.ruoyi.project.modules.parameter.domain.ParamsFieldRelation;
import com.ruoyi.project.modules.parameter.mapper.InterfaceParamsFieldRelationMapper;
import com.ruoyi.project.modules.parameter.mapper.ParamsFieldRelationMapper;
import com.ruoyi.project.modules.tableRelation.domain.TableRelation;
import com.ruoyi.project.modules.tableRelation.mapper.TableRelationMapper;
import com.ruoyi.project.modules.userDataAuth.domain.UserDataAuth;
import com.ruoyi.project.modules.userDataAuth.mapper.UserDataAuthMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.project.modules.table.domain.FieldInfo;
import com.ruoyi.project.modules.table.mapper.TableInfoMapper;
import com.ruoyi.project.modules.table.domain.TableInfo;
import com.ruoyi.project.modules.table.service.ITableInfoService;
import com.ruoyi.common.core.text.Convert;

import javax.annotation.Resource;

/**
 * 类对象信息Service业务层处理
 *
 * @author smallrain
 * @date 2021-10-28
 */
@Service
public class TableInfoServiceImpl implements ITableInfoService {

    @Resource
    private TableInfoMapper tableInfoMapper;

    /**
     * 查询类对象信息
     *
     * @param id 类对象信息主键
     * @return 类对象信息
     */
    @Override
    public TableInfo selectTableInfoById(Long id) {
        return tableInfoMapper.selectTableInfoById(id);
    }

    /**
     * 查询类对象信息列表
     *
     * @param tableInfo 类对象信息
     * @return 类对象信息
     */
    @Override
    public List<TableInfo> selectTableInfoList(TableInfo tableInfo) {
        return tableInfoMapper.selectTableInfoList(tableInfo);
    }

    /**
     * 新增类对象信息
     *
     * @param tableInfo 类对象信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertTableInfo(TableInfo tableInfo) {
        tableInfo.setCreateBy(ShiroUtils.getLoginName());
        tableInfo.setCreateTime(DateUtils.getNowDate());
        try {
            int rows = tableInfoMapper.insertTableInfo(tableInfo);
            insertFieldInfo(tableInfo);
            return rows;
        } catch (DuplicateKeyException e) {
            throw new BusinessException("别名重复");
        }
    }

    /**
     * 修改类对象信息
     *
     * @param tableInfo 类对象信息
     * @return 结果
     */
    @Transactional
    @Override
    public synchronized int updateTableInfo(TableInfo tableInfo) {
        try {
            tableInfo.setUpdateBy(ShiroUtils.getLoginName());
            tableInfo.setUpdateTime(DateUtils.getNowDate());
            tableInfoMapper.deleteFieldInfoByTableId(tableInfo.getId());
            tableRelationMapper.deleteTableRelationByMasterTableId(tableInfo.getId());
            insertFieldInfo(tableInfo);
            return tableInfoMapper.updateTableInfo(tableInfo);
        } catch (DuplicateKeyException e) {
            throw new BusinessException("别名重复");
        }
    }

    @Resource
    private UserDataAuthMapper userDataAuthMapper;


    /**
     * 批量删除类对象信息
     *
     * @param ids 需要删除的类对象信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteTableInfoByIds(String ids) {
        tableInfoMapper.deleteFieldInfoByTableIds(Convert.toStrArray(ids));
        userDataAuthMapper.removeByObjectId(Convert.toLongList(ids), "4");
        return tableInfoMapper.deleteTableInfoByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除类对象信息信息
     *
     * @param id 类对象信息主键
     * @return 结果
     */
    @Override
    public int deleteTableInfoById(Long id) {
        tableInfoMapper.deleteFieldInfoByTableId(id);
        return tableInfoMapper.deleteTableInfoById(id);
    }

    @Override
    public List<FieldInfo> selectFieldInfoList(List<Long> filedIds) {
        return tableInfoMapper.selectFieldInfoList(filedIds);
    }

    @Override
    public List<InterfaceInfo> interfaceList(Long tableId) {
        return tableInfoMapper.interfaceList(tableId);
    }

    @Override
    public List<FieldInfo> fieldInfoList(FieldInfo fieldInfo) {
        return tableInfoMapper.fieldInfoList(fieldInfo);
    }

    @Override
    public List<TableInfo> selectTableInfoByTableIds(List<Long> tableIds) {
        return tableInfoMapper.selectTableInfoByTableIds(tableIds);
    }

    @Override
    public List<TableInfo> selectTableInfoByTableIdsV2(List<Long> tableIds) {
        List<TableInfo> list = tableInfoMapper.selectTableInfoByTableIdsV2(tableIds);
        if (null == list || list.size() == 0) {
            return null;
        }
        // 循环查询出用户角色
        list.forEach(a -> {
            UserDataAuth userDataAuth = new UserDataAuth();
            userDataAuth.setObjectId(a.getId());
            userDataAuth.setObjectType("4");
            List<UserDataAuth> userList = userDataAuthMapper.selectUserDataAuthListV2(userDataAuth);
            if (null == userList || userList.size() == 0) {
                return;
            }
            a.setUserList(userList);
        });
        return list;
    }

    @Override
    public void updateTableStatus(TableInfo tableInfo) {
        this.tableInfoMapper.updateTableInfo(tableInfo);
    }

    @Override
    public List<TableRelation> selectTableInfoByRelation(Long tableId) {
        return this.tableInfoMapper.selectTableInfoByRelation(tableId);
    }

    @Override
    public List<FieldInfo> selectFieldInfoByFieldId(List<Long> fieldIds) {
        return this.tableInfoMapper.selectFieldInfoByFieldId(fieldIds);
    }

    @Resource
    private ParamsFieldRelationMapper paramsFieldRelationMapper;

    @Resource
    private InterfaceParamsFieldRelationMapper interfaceParamsFieldRelationMapper;

    @Override
    @Transactional
    public void updateFieldDesign(FieldInfo fieldInfo) {
        this.tableInfoMapper.updateFieldDesign(fieldInfo);
        //List<FieldInfo> fieldInfoList = this.tableInfoMapper.selectFieldInfoByFieldId(Arrays.asList(fieldInfo.getId()));
        InterfaceParamsFieldRelation interfaceParamsFieldRelation = new InterfaceParamsFieldRelation();
        interfaceParamsFieldRelation.setObjectId(fieldInfo.getId());
        //interfaceParamsFieldRelation.setIsRequired(fieldInfo.getIsRequired());
        interfaceParamsFieldRelation.setFieldDescription(fieldInfo.getFieldDescription());
        interfaceParamsFieldRelation.setDesignContent(fieldInfo.getDesignContent());
        interfaceParamsFieldRelation.setIsUpdate("N");
        this.interfaceParamsFieldRelationMapper.updateInterfaceParamsFieldRelationByFieldId(interfaceParamsFieldRelation);
        ParamsFieldRelation paramsFieldRelation = new ParamsFieldRelation();
        paramsFieldRelation.setFieldId(fieldInfo.getId());
       // paramsFieldRelation.setIsRequired(fieldInfo.getIsRequired());
        paramsFieldRelation.setFieldDescription(fieldInfo.getFieldDescription());
        paramsFieldRelation.setDesignContent(fieldInfo.getDesignContent());
        paramsFieldRelation.setIsUpdate("N");
        this.paramsFieldRelationMapper.updateParamsFieldRelationByFieldId(paramsFieldRelation);
    }

    @Override
    public void refreshData() {
        List<FieldInfo> fieldInfoList = this.tableInfoMapper.selectFieldInfos();
        for (FieldInfo fieldInfo : fieldInfoList) {
            fieldInfo.setMysqlFieldName(StrUtil.toUnderlineCase(fieldInfo.getFieldEnName()));
            this.tableInfoMapper.updateFieldInfo(fieldInfo);
        }
    }

    @Override
    public List<FieldInfo> queryFieldInfoList(FieldInfo fieldInfo) {
        return this.tableInfoMapper.queryFieldInfoList(fieldInfo);
    }

    @Resource
    private TableRelationMapper tableRelationMapper;
    /**
     * 新增字段信息信息
     *
     * @param tableInfo 类对象信息对象
     */
    public void insertFieldInfo(TableInfo tableInfo) {
        List<FieldInfo> fieldInfoList = tableInfo.getFieldInfoList();
        Long id = tableInfo.getId();
        String tableRelationInfo = tableInfo.getTableRelationInfo();
        if (StringUtils.isNotNull(fieldInfoList)) {
            List<FieldInfo> list = new ArrayList<FieldInfo>();
            List<FieldInfo> list2 = new ArrayList<FieldInfo>();
            Map<String, Boolean> fieldNameMap = new HashMap<>();
            Map<String, Boolean> fieldEnNameMap = new HashMap<>();
            for (FieldInfo fieldInfo : fieldInfoList) {
                if (fieldNameMap.containsKey(id + fieldInfo.getFieldName())) {
                    if(!(id.toString().equals("209") || id.toString().equals("234"))){
                        throw new BusinessException("字段中文名称重复");
                    }
                } else {
                    fieldNameMap.put(id + fieldInfo.getFieldName(), true);
                }

                if (fieldEnNameMap.containsKey(id + fieldInfo.getFieldEnName())) {
                    if(!(id.toString().equals("209") || id.toString().equals("234"))){
                        throw new BusinessException("字段英文名称重复");
                    }
                } else {
                    fieldEnNameMap.put(id + fieldInfo.getFieldEnName(), true);
                }

                fieldInfo.setTableId(id);
                fieldInfo.setMysqlFieldName(StrUtil.toUnderlineCase(fieldInfo.getFieldEnName()));
                if ("N".equals(fieldInfo.getIsFieldEnum())) {
                    fieldInfo.setDictId(null);
                }
                if (fieldInfo.getId() == null) {
                    list.add(fieldInfo);
                } else {
                    list2.add(fieldInfo);
                }
            }
            try {
                if (list.size() > 0) {
                    tableInfoMapper.batchFieldInfo(list);
                }
                if (list2.size() > 0) {
                    tableInfoMapper.batchFieldInfo2(list2);
                }
            } catch (DuplicateKeyException e) {
                throw new BusinessException("字段或者字段名称重复");
            }
            if (fieldInfoList.size() > 0) {
                if (StringUtils.isNotEmpty(tableRelationInfo) && tableRelationInfo.length() > 2) {
                    JSONObject jsonObject = JSONObject.parseObject(tableRelationInfo);
                    List<TableRelation> tableRelationList = new ArrayList<>();
                    for (int i = 0; i < fieldInfoList.size(); i++) {
                        if ("2".equals(fieldInfoList.get(i).getFieldType())) {
                            JSONArray jsonArray = jsonObject.getJSONArray(fieldInfoList.get(i).getRecordIndex() + "");
                            if (jsonArray != null) {
                                for (int j=0; j<jsonArray.size(); j++) {
                                    TableRelation tableRelation = jsonArray.getObject(j, TableRelation.class);
                                    tableRelation.setMasterFieldId(fieldInfoList.get(i).getId());
                                    tableRelation.setMasterTableId(id);
                                    tableRelationList.add(tableRelation);
                                }
                            }
                        }
                    }
                    if (tableRelationList.size() > 0) {
                        tableRelationMapper.batchSave(tableRelationList);
                    }
                }
            }
        }
    }
}
